package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

// 结构体标签 `key:value`对结构体进行说明
// 其他包在引用结构体时，可以通过标签查看本结构体该怎么用
type resume struct {
	Name string `info:"name" doc:"我的名字"`
	Sex  string `info:"sex"`
}

func findTag(str interface{}) {
	t := reflect.TypeOf(str).Elem() // str结构体中的元素
	for i := 0; i < t.NumField(); i++ {
		tagstring := t.Field(i).Tag.Get("info")
		tagdoc := t.Field(i).Tag.Get("doc")
		fmt.Println("info: ", tagstring, " doc: ", tagdoc)
	}
}
func main() {
	var re resume
	findTag(&re)

	movie := Movie{"千王之王", 2000, 10, []string{"周星驰", "张家辉"}}
	// 结构体-->json，带标签，转换json后，key值为标签值
	jsonStr, err := json.Marshal(movie)
	if err != nil {
		fmt.Println("json marshal error", err)
		return
	} else {
		fmt.Printf("结构体转换成json格式对象，同时使用标签：jsonStr = %s\n", jsonStr)
	}

	movie2 := Movie2{"战狼", 2020, 56, []string{"吴京"}}
	// 结构体-->json，带标签，转换json后，key值为属性名
	jsonStr2, err := json.Marshal(movie2)
	if err != nil {
		fmt.Println("json marshal error", err)
		return
	} else {
		fmt.Printf("结构体转换成json格式对象，没有使用标签：jsonStr2 = %s\n", jsonStr2)
	}

	// json-->结构体
	myMovie := Movie{}
	err = json.Unmarshal(jsonStr, &myMovie)
	if err != nil {
		fmt.Println("json unmarshal error", err)
		return
	} else {
		fmt.Printf("json格式对象转换成结构体 ： myMovie = %v\n", myMovie)
	}
}

type Movie struct {
	Title  string   `json:"title"`
	Year   int      `json:"yearear"`
	Price  int      `json:"piaofang"`
	Actors []string `json:"actors"`
}

type Movie2 struct {
	Title  string
	Year   int
	Price  int
	Actors []string
}
